class MagicBox03<T>(item:T) {
    var available = false
    private var subject:T = item
    fun fetch():T?{
        return subject.takeIf { available }
    }

    fun<R> fetch(subjectModFunction:(T) -> R):R?{
        return subjectModFunction(subject).takeIf { available }
    }
}

class Boy03(val name:String, val age: Int)
class Man(val name:String, val age: Int)
class Dog03(val weight:Int)

fun main() {
    val magicBox:MagicBox03<Boy03> = MagicBox03(Boy03("jack", 80))
    val magicBox1:MagicBox03<Dog03> = MagicBox03(Dog03(90))
    magicBox.available = true
    magicBox.fetch()?.run {
        println("you find $name")
    }

    val man = magicBox.fetch {
        Man(it.name, it.age.plus(15))
    }
}